﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;
using System.Threading;

namespace PictureTransform
{
    public class ImageProcessing
    {
        private ImageCodecInfo imageCodec;
        private EncoderParameters encoderParameters;

        public ImageProcessing()
        {
            // Encoding parameters
            imageCodec = (from codec in ImageCodecInfo.GetImageEncoders()
                                  where codec.MimeType == "image/jpeg"
                                  select codec).Single();

            encoderParameters = new EncoderParameters();
            encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
        }

        public void NormalizeRotation(IEnumerable<string> files, AutoResetEvent stopSignal, Action<string> progressCallback)
        {
            foreach (var filepath in files)
            {
                try
                {
                    // Check image orientation

                    using (var originalImage = new Bitmap(filepath))
                    {
                        // http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem.id.aspx
                        var PropertyTagOrientation = 0x0112;
                        var prop = originalImage.PropertyItems.Where(p => p.Id == PropertyTagOrientation).SingleOrDefault();

                        var orientation = prop != null ? (int)(prop.Value[0]) : 1;

                        // http://sylvana.net/jpegcrop/exif_orientation.html
                        //Value	0th Row	    0th Column
                        //
                        // 1	top	        left side
                        // 2	top	        right side - flip horizontal
                        // 3	bottom	    right side - rotate 180 CW
                        // 4	bottom	    left side  - filp vertical
                        // 5	left side	top        - rotate 90 CW, flip horizontal 
                        // 6	right side	top        - rotate 90 CW
                        // 7	right side	bottom     - rotate 270 CW, flip horizontal
                        // 8	left side	bottom     - rotate 270 CCW

                        var transform = new List<RotateFlipType>{
                                    RotateFlipType.RotateNoneFlipNone,  // 1 
                                    RotateFlipType.RotateNoneFlipX,     // 2
                                    RotateFlipType.Rotate180FlipNone,   // 3
                                    RotateFlipType.RotateNoneFlipY,     // 4
                                    RotateFlipType.Rotate90FlipX,       // 5
                                    RotateFlipType.Rotate90FlipNone,    // 6
                                    RotateFlipType.Rotate270FlipX,      // 7
                                    RotateFlipType.Rotate270FlipNone,   // 8
                        };

                        //Rotate if necessary
                        if (transform[orientation - 1] != RotateFlipType.RotateNoneFlipNone)
                        {

                            originalImage.RotateFlip(transform[orientation - 1]);

                            // Save rotated image
                            prop.Value[0] = 1;
                            originalImage.SetPropertyItem(prop);
                            originalImage.Save(filepath, imageCodec, encoderParameters);
                        }
                    }
                }
                catch(Exception)
                {
                    // TODO: Log error
                }

                if (stopSignal != null && stopSignal.WaitOne(0))
                    return;

                if (progressCallback != null)
                    progressCallback(filepath);
            }
        }
    }
}
